#pragma once
/**
 * 校园智能快递集散系统
 * 程序设计基础课程设计
 * 本文件包含数据持久化模块的接口定义
 */

#ifndef FILEIO_H
#define FILEIO_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <direct.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>

#include "system_types.h"

 // 文件路径常量
#define DATA_DIR "./data"
#define USERS_FILE "./data/users.csv"
#define PACKAGES_FILE "./data/packages.csv"
#define SHELVES_FILE "./data/shelves.csv"
#define LOGS_FILE "./data/logs.csv"
#define NOTIFICATIONS_FILE "./data/notifications.csv"

// CSV 文件分隔符
#define CSV_DELIMITER ","
#define CSV_QUOTE "\""
#define CSV_NEWLINE "\n"

/**
 * 将CSV字符串进行转义处理
 *
 * 将字符串中的特殊字符（如逗号、引号、换行符）进行适当转义，
 * 以便安全地存储在CSV文件中。
 *
 * @param str 需要转义的字符串
 * @return 转义后的字符串，使用后需要手动释放内存
 */
char* escapeCSV(const char* str);

/**
 * 将已转义的CSV字符串恢复为原始字符串
 *
 * @param str 已转义的字符串
 * @return 恢复后的原始字符串，使用后需要手动释放内存
 */
char* unescapeCSV(const char* str);

/**
 * 将字符串拆分为CSV字段数组
 *
 * @param line 输入的CSV行字符串
 * @param fieldCount 输出参数，返回字段数量
 * @return 字段字符串数组，使用后需要通过freeCSVFields释放内存
 */
char** splitCSVLine(char* line, int* fieldCount);

/**
 * 释放由splitCSVLine函数创建的字段数组
 *
 * @param fields 字段数组
 * @param fieldCount 字段数量
 */
void freeCSVFields(char** fields, int fieldCount);

/**
 * 将字段数组写入CSV文件
 *
 * @param file 已打开的文件指针
 * @param fields 字段数组
 * @param fieldCount 字段数量
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode writeCSVLine(FILE* file, char** fields, int fieldCount);

/**
 * 获取当前时间的格式化字符串
 *
 * @param buffer 输出缓冲区
 * @param bufferSize 缓冲区大小
 */
void getTime(char* buffer, size_t bufferSize);

/**
 * 检查并创建数据目录
 *
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode createDataDirectoryIfNotExists();

/**
 * 检查文件是否存在，不存在则创建空文件
 *
 * @param filePath 文件路径
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode createEmptyFileIfNotExists(const char* filePath);

/**
 * 将用户数据保存到CSV文件
 *
 * @param data 系统数据结构指针
 * @param filePath 目标文件路径
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode saveUsersToFile(SystemData* data, const char* filePath);

/**
 * 将包裹数据保存到CSV文件
 *
 * @param data 系统数据结构指针
 * @param filePath 目标文件路径
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode savePackagesToFile(SystemData* data, const char* filePath);

/**
 * 将货架数据保存到CSV文件
 *
 * @param data 系统数据结构指针
 * @param filePath 目标文件路径
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode saveShelvesToFile(SystemData* data, const char* filePath);

/**
 * 将日志数据保存到CSV文件
 *
 * @param data 系统数据结构指针
 * @param filePath 目标文件路径
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode saveLogsToFile(SystemData* data, const char* filePath);

/**
 * 将通知数据保存到CSV文件
 *
 * @param data 系统数据结构指针
 * @param filePath 目标文件路径
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode saveNotificationsToFile(SystemData* data, const char* filePath);

/**
 * 从CSV文件加载用户数据
 *
 * @param data 系统数据结构指针
 * @param filePath 源文件路径
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode loadUsersFromFile(SystemData* data, const char* filePath);

/**
 * 从CSV文件加载包裹数据
 *
 * @param data 系统数据结构指针
 * @param filePath 源文件路径
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode loadPackagesFromFile(SystemData* data, const char* filePath);

/**
 * 从CSV文件加载货架数据
 *
 * @param data 系统数据结构指针
 * @param filePath 源文件路径
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode loadShelvesFromFile(SystemData* data, const char* filePath);

/**
 * 从CSV文件加载日志数据
 *
 * @param data 系统数据结构指针
 * @param filePath 源文件路径
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode loadLogsFromFile(SystemData* data, const char* filePath);

/**
 * 从CSV文件加载通知数据
 *
 * @param data 系统数据结构指针
 * @param filePath 源文件路径
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode loadNotificationsFromFile(SystemData* data, const char* filePath);

/**
 * 初始化系统数据文件
 *
 * 确保数据目录和所有必要的数据文件存在。
 *
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode initDataFiles();

/**
 * 将系统所有数据保存到文件
 *
 * @param data 系统数据结构指针
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode saveSystemData(SystemData* data);

/**
 * 从文件加载系统所有数据
 *
 * @param data 系统数据结构指针
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode loadSystemData(SystemData* data);

#endif // FILEIO_H